﻿
using System.Diagnostics;
using System.Linq;
using FakeItEasy;
using FluentAssertions;
using Wolfpack.Contrib.Deployment;
using Wolfpack.Contrib.Deployment.Exe;
using Wolfpack.Contrib.Deployment.NUnit;
using Wolfpack.Core.Interfaces.Entities;

namespace Wolfpack.Contrib.Tests.Publishers.Deployment
{

    public class NUnitDeploymentPublisherDomain : DeploymentPublisherDomainBase<NUnitDeploymentConfig>
    {
        public const string ExpectedXmlResultsFile = @"c:\testing\results\testresults.xml";
        
        private readonly IProcessLauncher _launcher;
        private ProcessStartInfo _actualLauncherProcessArg;
        private int _launcherResult;

        private NUnitResult _testResult;
        private string _actualTestResultFile;
        private INUnitResultFileParser _parser;

        public NUnitDeploymentPublisherDomain()
        {
            SetDeploymentBaseConfig(_config = new NUnitDeploymentConfig
                          {
                              ResultsFile = ExpectedXmlResultsFile,
                              Command = @"nunit-console-x86.exe UnderTest\Wolfpack.Contrib.nunit /xml=UnderTest\wolfpack.contrib.results.xml"
                          });
            _testResult = new NUnitResult();

            _launcher = A.Fake<IProcessLauncher>();
        }

        public void TheUnitTestResultContainsNoFailuresErrorsOrInvalidTests()
        {
            _testResult.Errors = 0;
            _testResult.Failures = 0;
            _testResult.Invalid = 0;
        }

        public void TheDataMessageShouldContainTheTestResultAsProperties()
        {
            var msg = Agent.NotificationEvents.First(n => n.EventType == NotificationEventHealthCheck.EventTypeName);

            typeof(NUnitResult).GetProperties().ToList()
                .ForEach(pi => msg.Properties.ContainsKey(pi.Name).Should().BeTrue());
        }

        public void TheFilenameTheParserIsCalledWithIsTheSameAsTheConfig()
        {
            _actualTestResultFile.Should().Be(ExpectedXmlResultsFile);
        }

        public void TheUnitTestResultFailuresIsSetTo_(int count)
        {
            _testResult.Failures = count;
        }

        public void TheUnitTestResultErrorsIsSetTo_(int count)
        {
            _testResult.Errors = count;
        }

        public void TheXmlFileParserWithResultFile(string filename)
        {
            _parser = new NUnitXmlResultFileParser();
            _actualTestResultFile = filename;
        }

        public void TheParserIsInvoked()
        {
            _testResult = _parser.Parse(_actualTestResultFile);
        }

        public void TheUnitResultShouldBeValid()
        {
            _testResult.Should().NotBeNull();
        }

        public void TheUnitTestResultShouldHave_Errors(int expected)
        {
            _testResult.Errors.Should().Be(expected);
        }

        public void TheUnitTestResultShouldHave_Failures(int expected)
        {
            _testResult.Failures.Should().Be(expected);
        }

        public void TheUnitTestResultShouldHave_NotRun(int expected)
        {
            _testResult.NotRun.Should().Be(expected);
        }

        public void TheUnitTestResultShouldHave_Inconclusive(int expected)
        {
            _testResult.Inconclusive.Should().Be(expected);
        }

        public void TheUnitTestResultShouldHave_Ignored(int expected)
        {
            _testResult.Ignored.Should().Be(expected);
        }

        public void TheUnitTestResultShouldHave_Skipped(int expected)
        {
            _testResult.Skipped.Should().Be(expected);
        }

        public void TheUnitTestResultShouldHave_Invalid(int expected)
        {
            _testResult.Invalid.Should().Be(expected);
        }

        public void TheUnitTestResultShouldHave_Total(int expected)
        {
            _testResult.Total.Should().Be(expected);
        }

        public void ThePublisherIsCalled()
        {
            A.CallTo(() => _launcher.Launch(A<ProcessStartInfo>.Ignored))
                            .Invokes(call =>
                            {
                                _actualLauncherProcessArg = (ProcessStartInfo)call.Arguments[0];
                            })
                            .Returns(_launcherResult);

            var fakeParser = A.Fake<INUnitResultFileParser>();
            A.CallTo(() => fakeParser.Parse(A<string>.Ignored))
                .Invokes(call =>
                {
                    _actualTestResultFile = call.Arguments[0].ToString();
                })
                .Returns(_testResult);

            var sut = new NUnitDeploymentPublisher(_config)
            {
                Launcher = _launcher,
                Updater = _updater,
                ResultParser = fakeParser
            };

            sut.Consume(_triggerNotification);
        }

        public void TheCommandLine_(string cmd)
        {
            _config.Command = cmd;
        }

        public void TheLauncherIndicatesSuccess()
        {
            _launcherResult = 0;
        }

        public void TheLauncherReturnsErrorCode_(int errorCode)
        {
            _launcherResult = errorCode;
        }

    }
}